'use strict';

webappApp.controller('CreateCtrl', ['$scope', '$location', '$filter', 'thumbnailFactory', 'photoReader', 'spotService', 'photoService', 'addresses', 'geo', function($scope, $location, $filter, thumbnailFactory, photoReader, spotService, photoService, addresses, geo) {
  var spot = $scope.spot = { photos: {} },

  total = 1,
  customLocation,

  getPhoto = function (name) {
    return spot.photos[name] || {};
  },

  // XHR callbacks
  onProgress = function (file, e) {
    $scope.$apply(function () {
      if (e.lengthComputable) {
        file.progress = (e.loaded / e.total) * 100;
      }
    });
  },
  onLoad = function (file, e) {
    $scope.$apply(function() {
      file.progress = 100;
    });
  },
  onError = function (file, e) {
    $scope.$apply(function(file) {
      file.status = 'error';
    });
  };

  $scope.photos = photoService;

  $scope.handleDragEnd = function (m) {
    customLocation = {
      latitude: m.position.lat(),
      longitude: m.position.lng()
    };
    $scope.setLocation(customLocation);
  };

  $scope.setLocation = function (location) {
    spot.location = location;
    $scope.marker.setMap(location ? $scope.map : null);
    $scope.marker.setPosition(new google.maps.LatLng(
      location.latitude, 
      location.longitude
    ));
    if (location) {
      addresses.getAddress(location, $scope).
        then(function(address) {
          spot.address = address;
        });
    } else {
      spot.address = undefined;
    }
  };

  $scope.marker = $filter('marker')({ latitude: 0, longitude: 0 },
                                    null,
                                    { draggable: true });
  // $scope.marker.addListener('dragend', $scope.setLocation);

  $scope.submit = function (spot) {
    var id, photos = spot.photos;
    angular.forEach(photos, function (p) {
      p.progress = 0;
      p.onload = onLoad;
      p.onerror = onError;
      p.onprogress = onProgress;
    });
    spot.photos = undefined;
    spotService.create(spot, function(created) {
      angular.forEach(photos, function (p) {
        p.id = created.id;
        photoService.upload(p);
      });
      $scope.spot = created;
    });
  };

  $scope.cancel = function (file) {
    file.progress = 0;
  };

  $scope.getProgress = function () {
    var progress = 0;
    angular.forEach(spot.photos, function (p) {
      progress = progress + (p.progress || 0);
    });
    progress = (progress / total) * 100;
    if (progress == 100) {
      progress = 0;
    }
    spot.ready = progress === 0;
    return progress;
  };

  $scope.clear = function () {
    total = 1;
    spot.photos = {};
    $scope.setLocation(undefined);
    spot.ready = false;
    customLocation = undefined;
  };

  $scope.readFiles = function (fileList) {
    total = fileList.length * 100;
    spot.ready = false;
    angular.forEach(fileList, function (f) {
      thumbnailFactory.create(f,
        function (thumb) {
          $scope.$apply(function() {
            var photo = getPhoto(f.name);
            if (!photo.file) {
              photo.file = f;
            }
            photo.name = f.name;
            photo.thumb = thumb;
            photo.progress = 100;
            spot.photos[f.name] = photo;
          });
        },
        function (progress) {
          $scope.$apply(function() {
            var photo = getPhoto(f.name);
            photo.progress = progress;
          });
        });
      photoReader.read(f, function(meta) {
        $scope.$apply(function() {
          var photo = spot.photos[f.name] || {};
          if (meta &&
              meta.gps &&
              meta.gps.latitude && meta.gps.longitude &&
              angular.isNumber(meta.gps.latitude.value) &&
              angular.isNumber(meta.gps.longitude.value)) {
            photo.location = {
              latitude: meta.gps.latitude.value,
              longitude: meta.gps.longitude.value
            };
          }
          if (!photo.file) {
            photo.file = f;
          }
          photo.orientation = meta.tiff.Orientation.value;
          spot.photos[f.name] = photo;
          $scope.setLocation(customLocation || geo.center(spot.photos));
        });
      });
    });
  };
}]);
